﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using RGBFinder.Resources;
using System.Threading;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using mmiWP7SDK;
using Microsoft.Advertising.Mobile.UI;

namespace RGBFinder
{
    public partial class NewGamePage : PhoneApplicationPage
    {
        Random rnd = new Random();
                
        public static bool start_new_game = false;

        public NewGamePage()
        {
            InitializeComponent();

            AdControl.TestMode = false;

            buttons = new List<Button>()
            {
                button1,button2,button3,button4,button5,button6,button7,button8,button9,button10,
                button11,button12,button13,button14,button15,button16,button17,button18,button19,button20,
                button21,button22,button23,button24,button25,button26,button27,button28,button29,button30,
                button31,button32,button33,button34,button35,button36
            };

            cells = new List<Rectangle>()
            {
                rectangle1,rectangle2,rectangle3,rectangle4,rectangle5,rectangle6,rectangle7,rectangle8,rectangle9,rectangle10,
                rectangle11,rectangle12,rectangle13,rectangle14,rectangle15,rectangle16,rectangle17,rectangle18,rectangle19,rectangle20,
                rectangle21,rectangle22,rectangle23,rectangle24,rectangle25,rectangle26,rectangle27,rectangle28,rectangle29,rectangle30,
                rectangle31,rectangle32,rectangle33,rectangle34,rectangle35,rectangle36

            };

            var difficulty = StateAndOptions.state.last_difficulty; ;
            float difficulty_mult = (3+(int)difficulty+((int)difficulty/2)) / 6f;
            int num_c = (int)(6 * difficulty_mult);

            var butts = new List<Button>();
            for (int i = 0; i < num_c; i++)
            {
                CellsGrid.ColumnDefinitions[i].Width = new GridLength(80*(1f/difficulty_mult));
                CellsGrid.RowDefinitions[i + 1].Height = new GridLength(80 * (1f / difficulty_mult));
                for (int j = 0; j < num_c; j++)
                {
                    var button = buttons[i * 6 + j];
                    button.Width = 79 * (1f / difficulty_mult);
                    button.Height = 79 * (1f / difficulty_mult);
                    butts.Add(button);
                }
            }
            for (int i = num_c; i < 6; i++)
            {
                CellsGrid.ColumnDefinitions[i].Width = new GridLength(0);
                CellsGrid.RowDefinitions[i + 1].Height = new GridLength(0);
            }

            cells = cells.Where((c, i) => butts.Contains(buttons[i])).ToList();
            buttons = butts;

        }



        private void Slider_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {

        }

        #region ACTIVATE_DEACTIVATE

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            StateAndOptions.SaveState();
        }

        //public static bool game_finished = false;
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
        }
        #endregion


        List<Button> buttons = new List<Button>();
        List<Rectangle> cells = new List<Rectangle>();
        List<Button> tapped = new List<Button>();
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (StateAndOptions.state.scores.Count > 0)
                textBlock3.Text = Strings.LoaclHighScore + Math.Max(current_score, StateAndOptions.state.scores.OrderByDescending(s => s.score).First().score);
            buttons.ForEach(c =>
                {
                    //c.IsHitTestVisible = false;
                    c.Click += new RoutedEventHandler(
                        (object send, RoutedEventArgs ev) =>
                        {
                            if (showing || sequence.Count==0)
                                return;
                            tapped.Add(c);
                            CheckSequence();
                        });
                     
                });



            updateScore();
            if (StateAndOptions.state.scores.Count > 0)
            {
                var top = StateAndOptions.state.scores.OrderByDescending(s => s.score).First();
                textBlock3.Text = Strings.LoaclHighScore + Math.Max(current_score, top.score);
                WebConnection.requestPosition(top.name, "" + top.level, "" + top.score, top.datetime,
                    (pos) =>
                    {
                        Dispatcher.BeginInvoke(() => { textBlock4.Text = Strings.GlobalRank + ": " + pos; });
                    }, () => { });

            }
        }

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {   
            
            if (MessageBox.Show(Strings.AreYouSureToExit, "", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                e.Cancel = true;
                            
        }

        int level = 1;
        private void button37_Click(object sender, RoutedEventArgs e)
        {
            button37.Visibility = System.Windows.Visibility.Collapsed;
            GenerateSequence(3 + (int)Math.Pow(level,1/4f));
            ShowSequence();
        }

        private void updateScore()
        {
            textBlock1.Text = Strings.Level+" " + level;
            textBlock2.Text = Strings.Score1+" " + current_score;
        }

        Random r = new Random();
        int global_rank;
        private void GenerateSequence(int num)
        {
            tapped.Clear();
            sequence.Clear();
            for (int i = 0; i < num; )
            {
                var n = r.Next(cells.Count);
                if (sequence.Skip(Math.Max(0, sequence.Count-cells.Count() / 2 + 1)).Contains(buttons[n]))
                    continue;
                sequence.Add(buttons[n]);
                i++;
            }
        }

        DateTime time_levelstarted;
        List<Button> sequence = new List<Button>();
        bool showing = false;
        private void ShowSequence()
        {
            //button1.Background = new SolidColorBrush(Color.FromArgb(255, 233, 200, 34));
            showing = true;
            PageTitle.Text = Strings.Watch_;
            //button37.IsEnabled = false;
            Thread t = new Thread(new ThreadStart(
                () =>
                {
                    int i = 0;
                    while(i<sequence.Count)
                    {
                        System.Threading.Thread.Sleep(1000-level*level);
                        Dispatcher.BeginInvoke(() =>
                        {                            
                            if (i > 0)
                                 cells[buttons.IndexOf(sequence[i - 1])].Fill = new SolidColorBrush(Color.FromArgb(0, 255, 255, 0));
                            if (i < sequence.Count)
                                cells[buttons.IndexOf(sequence[i])].Fill = new SolidColorBrush(Color.FromArgb(255, 255, 255, 0));
                            i++;
                        });
                    }
                    Dispatcher.BeginInvoke(() =>
                    {
                        showing = false;
                        PageTitle.Text = Strings.Tap_;
                        time_levelstarted = System.DateTime.Now;
                        //button37.IsEnabled = true;
                    });
                }));
            t.Start();
        }

        int current_score = 0;
        private void CheckSequence()
        {
            bool correct=true;
            if (tapped.Count > sequence.Count)
            {
                correct = false;
            }
            else
            {
                for (int i = 0; i < tapped.Count; i++)
                {
                    if (tapped[i] != sequence[i])
                    {
                        correct = false;
                        break;
                    }
                }
            }

            if (correct)
            {
                if (tapped.Count == sequence.Count) //Completato
                {
                    var now = System.DateTime.Now;
                    current_score += (int)(level * (10 / (now - time_levelstarted).TotalSeconds) * Math.Pow(5, (int)StateAndOptions.state.last_difficulty - 1));
                    level++;
                    tapped.ForEach(c => { cells[buttons.IndexOf(c)].Fill = new SolidColorBrush(Color.FromArgb(255, 0, 255, 0)); });
                    new Thread(new ThreadStart(
                        () =>
                        {
                            Thread.Sleep(1000);                            
                            Dispatcher.BeginInvoke(() =>
                            {
                                tapped.ForEach(c => { cells[buttons.IndexOf(c)].Fill = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)); });
                                GenerateSequence(3 + (int)Math.Pow(level, 1 / 2f));
                                ShowSequence();
                            });                            
                        })).Start();
                    Dispatcher.BeginInvoke(() => { updateScore(); });
                }
            }
            else
            {
                
                showing=true;
                PageTitle.Text = Strings.Wrong_;
                Thread t = new Thread(new ThreadStart(
                () =>
                {
                    StateAndOptions.state.scores.Add(new Score()
                    {
                        name = StateAndOptions.state.last_nick,
                        score = current_score,
                        datetime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                        level = "" + (level)
                    });

                    if (StateAndOptions.state.scores.Count > 0)
                    {
                        Dispatcher.BeginInvoke(() =>
                        {
                            var top = StateAndOptions.state.scores.OrderByDescending(s => s.score).First();
                            textBlock3.Text = Strings.LoaclHighScore + Math.Max(current_score, top.score);

                            WebConnection.requestPosition(top.name, "" + top.level, "" + top.score, top.datetime,
                                (pos) =>
                                {
                                    Dispatcher.BeginInvoke(() => { textBlock4.Text = Strings.GlobalRank + ": " + pos; });
                                }, () => { });
                        });

                    }

                    Dispatcher.BeginInvoke(() => { updateScore(); });

                    level = 1;
                    current_score = 0;


                    Dispatcher.BeginInvoke(() =>
                           {
                               tapped.ForEach(c => { cells[buttons.IndexOf(c)].Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)); });
                           });
                    Thread.Sleep(1000);
                    Dispatcher.BeginInvoke(() =>
                        {

                            tapped.ForEach(c => cells[buttons.IndexOf(c)].Fill = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)));
                            showing = false;
                            button37.Visibility = System.Windows.Visibility.Visible;
                            PageTitle.Text = Strings.Start_;
                            tapped.Clear();
                        });

                }));
                t.Start();
            }
        }      
    
    }
}